/*
 * @(#) TableModel.java 2012-3-29 下午05:02:43
 *
 * Copyright 2012 Rockwell Automation, Inc. All rights reserved.
 * Rockwell Automation PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */package com.mesd.killer.table;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.table.AbstractTableModel;

import org.apache.commons.beanutils.BeanUtils;

import com.mesd.killer.util.StringUtil;

public class FTableObjModel extends AbstractTableModel
{
	Vector data = new Vector();
	FTableHeaderValue[] fTableHeaderValues;
	
	public FTableObjModel(FTableHeaderValue[] fTableHeaderValues,Vector data)
	{
		this.fTableHeaderValues = fTableHeaderValues;
		this.data = data;
	}
	
	public FTableObjModel(FTableHeaderValue[] fTableHeaderValues)
	{
		this.fTableHeaderValues = fTableHeaderValues;
	}
	
	public int getColumnCount()
	{
		return fTableHeaderValues.length;
	}

	public int getRowCount()
	{
		return data.size();
	}

	public Object getValueAt(int row, int col)
	{
		try 
		{
			if(row >= data.size()) return "";
				
			DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			DecimalFormat df = new DecimalFormat("#,###,##0.000");
			String key = fTableHeaderValues[col].getKey();
			if(StringUtil.isNull(key))
				return "";
			
			Object owner = data.get(row);
			if(owner == null)
				return null;
			
			Class rowObjectClass = owner.getClass();

			String methodName = key.substring(
				0, 1).toUpperCase() + key.substring(1);

			Method method = rowObjectClass.getMethod("get" + methodName);
			
			Field field = rowObjectClass.getDeclaredField(key);
			if ("java.util.Date".equals(field.getType().getName())
				|| "java.sql.Timestamp".equals(field.getType().getName()))
			{
				return method.invoke(owner) == null ? "" : format.format(method.invoke(owner));
			}
			else if (("java.math.BigDecimal").equals(field.getType().getName())
				|| ("java.util.Double").equals(field.getType().getName())
				|| ("java.lang.Double").equals(field.getType().getName()))
			{
				Object value = method.invoke(owner) == null ? 0.00 : df.format(method.invoke(owner));
				return value;
			}
			else
			{
				Object objString = method.invoke(owner) == null ? "" : method.invoke(owner);
				return objString;
			}
		} 
		catch (Exception e)
		{
			e.printStackTrace();
		} 
		
		return "";
	}

	public String getColumnName(int column)
	{
		if(fTableHeaderValues == null || fTableHeaderValues.length <= column)
			return "";
		
		return fTableHeaderValues[column].getName();
	}

	public Class getColumnClass(int col)
	{
		return getValueAt(
			0, col).getClass();
	}

	public boolean isCellEditable(int row, int col)
	{
		return true;
	}

	public void setValueAt(Object aValue, int row, int column)
	{
		try
		{
			if(column == 5 || column == 6)
				return ;
			if(data == null)
				data = new Vector();
			
			DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
			DecimalFormat df = new DecimalFormat("#,###,###.00");
			String key = fTableHeaderValues[column].getKey();
			if(StringUtil.isNull(key))
				return ;
			
			Object owner = data.get(row);
			if(owner == null)
				return ;
			
			Class rowObjectClass = owner.getClass();
			
			Field field = rowObjectClass.getDeclaredField(key);
			if ("java.util.Date".equals(field.getType().getName())
				|| "java.sql.Timestamp".equals(field.getType().getName()))
			{
				aValue = StringUtil.isNull(aValue.toString())? null : format.parse(aValue.toString());
			}
			else if (("java.math.BigDecimal").equals(field.getType().getName())
				|| ("java.util.Double").equals(field.getType().getName())
				|| ("java.lang.Double").equals(field.getType().getName()))
			{
				aValue =StringUtil.isNull(aValue.toString())? 0.00 : df.parse(aValue.toString()).doubleValue();
			}
			
			BeanUtils.setProperty(
				owner,key,aValue);
			fireTableCellUpdated(row, column);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public void addRows(List<Object> objs)
	{
		int rowCount = data.size();
		data.removeAllElements();
		if(objs == null)
			return ;
		
		for(int i=0;i<objs.size();i++)
		{
			data.insertElementAt(objs.get(i),i);
		}
		
		super.fireTableChanged(null);
		super.fireTableDataChanged();
	}
	
	public void insertRow(int row,Object o)
	{
		Object rowObject = data.get(row);
		data.insertElementAt(o, row);
		
		super.fireTableRowsInserted(row, row);
	}
	
	public Object removeRow(int row)
	{
		Object removedObject = data.get(row);
		if(removedObject != null)
		{
			data.removeElementAt(row);
			super.fireTableRowsDeleted(
				row, row);
		}
		
		return removedObject;
	}
	
	public Object getRow(int row)
	{
		if(row >= data.size())
			return null;
		
		return data.get(row);
	}
	
	public List<Object> removeRows(int[] rows)
	{
		List<Object> removedObjsList = new ArrayList<Object>();
		for(int i:rows)
		{
			removedObjsList.add(data.get(i));
			data.removeElementAt(i);
			super.fireTableRowsDeleted(i, i);
		}
		
		return removedObjsList;
	}
	
	public void removeAll()
	{
		data.removeAllElements();
		super.fireTableDataChanged();
	}
	
	public Vector<Object> getAllData()
	{
		return data;
	}
}
